package com.self.cloudmall.wms.mq;

import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.rabbitmq.client.Channel;
import com.self.cloudmall.common.dto.OrderDto;
import com.self.cloudmall.common.dto.StockLockDto;
import com.self.cloudmall.wms.service.WareSkuService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.List;

@Slf4j
@Component
@RabbitListener(queues = {"stock.release.queue"})
public class StockReleaseMqHandler {

    @Autowired
    private WareSkuService wareSkuService;

    /**
     * 适用场景：
     * 1.库存自动解锁
     *   订单创建成功，库存锁定成功，其他业务失败，导致订单回滚，库存锁定也要回滚
     * 2.订单失败
     *   锁库失败，不用处理
     * @param lockDtoList
     * @param message
     */
    @RabbitHandler
    public void handleStockLockRelease(List<StockLockDto> lockDtoList, Message message, Channel channel){
        try {
            String json = new String(message.getBody(), "UTF-8");
            log.info("库存锁定-解锁消息：{}",json);
            List<StockLockDto> stockLockDtos = JSONObject.parseObject(json, new TypeReference<List<StockLockDto>>() {
            });
            wareSkuService.unLockStock(stockLockDtos);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            log.error("库存解锁异常：{}",e);
            try {
                //拒绝签收消息，重新放入队列中
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
            } catch (Exception ex) {
                log.error("库存锁定-拒绝解锁异常：{}",ex);
            }
        }
    }

    /**
     * 订单解锁存储，因为订单关闭可能处理时间很长或者卡住，超过20分钟自动解锁库存的时间，
     *             就造成库存不能解锁库存
     * @param orderDto
     * @param message
     * @param channel
     */
    @RabbitHandler
    public void handleOrderStockLockRelease(OrderDto orderDto, Message message, Channel channel){
        log.info("订单号：{}的订单状态已经关闭后，进行解锁...",orderDto.getOrderSn());
        try{
            wareSkuService.unLockStock(orderDto);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (Exception e) {
            log.error("库存解锁异常：{}",e);
            try {
                //拒绝签收消息，重新放入队列中
                channel.basicReject(message.getMessageProperties().getDeliveryTag(),true);
            } catch (Exception ex) {
                log.error("订单状态已经关闭后-拒绝解锁异常：{}",ex);
            }
        }
    }
}
